package com.haiyou.data.common.accessor;

import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;

import org.apache.commons.lang3.Validate;

import com.google.common.collect.Maps;
import com.haiyou.common.entity.Entity;

/**
 * 数据访问接口，更新数据请务必使用compute方法，请勿直接get一个临时对象执行各种set操作，脱离了锁的约束
 * 
 * @author xingyuan
 *
 * @param <K>
 * @param <V>
 */
public interface Accessor<K extends Serializable & Comparable<K>, V extends Entity<K>> extends Map<K, V> {

	@Override
	default int size() {
		throw new NotImplementedException();
	}

	@Override
	default boolean isEmpty() {
		throw new NotImplementedException();
	}

	@Override
	default void clear() {
		throw new NotImplementedException();
	}

	@Override
	default Set<K> keySet() {
		throw new NotImplementedException();
	}

	@Override
	default Collection<V> values() {
		throw new NotImplementedException();
	}

	@Override
	default Set<Entry<K, V>> entrySet() {
		throw new NotImplementedException();
	}

	@Override
	default void forEach(BiConsumer<? super K, ? super V> action) {
		throw new NotImplementedException();
	}

	@Override
	default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
		throw new NotImplementedException();
	}

	default V get(K key, Function<? super K, ? extends V> mappingFunction) {
		return computeIfAbsent(key, mappingFunction);
	}

	Map<K, V> getAll(Iterable<? extends K> keys);

	void removeAll(Iterable<? extends K> keys);

	/** key的class类型 */
	Class<K> getKeyClass();

	/** value的class类型 */
	Class<V> getValueClass();

	/** 生成key */
	K generateKey();

	/**
	 * 生成实例，key是底层自动产生的，通常应该调用get(K key, Function<? super K, ? extends V>
	 * mappingFunction);
	 * 
	 * @param consumer 执行一些初始化操作
	 * @return
	 */
	V generate(Consumer<V> consumer);

	/** 生成实例 */
	default V generate() {
		return generate(null);
	}

	/**
	 * id管理器，负责生成ID，回收ID，重用ID等
	 * 
	 * @return
	 */
	default IdManager<K> getIdManager() {
		return null;
	}

	public static <A extends Accessor<?, ?>> A getInstance(Class<?> valueClass) {
		A instance = (A) pool.get(valueClass);
		Validate.isTrue(instance != null, "%s 的存储器不存在", valueClass);
		return instance;
	}

	static Map<Class<?>, Accessor<?, ?>> pool = Maps.newHashMap();

	/**
	 * 初始化封装得class 主要继承注释使用
	 * @return
	 */
	public abstract Class<?> getInitClass();
}
